package qy.jalgotrade.utils.resamplebase;

import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

import qy.jalgotrade.bar.Bar;
import qy.qyalgotrader.utils.CommonDataUtils;

/**
 * ZoneId: "UTC"
 * 
 * @author qy
 *
 */
public abstract class TimeRange {

	/**
	 * 08:00:00
	 */
	public static final LocalTime DAY_TRADE_BEGIN_TIME = LocalTime.parse("08:00:00",
			DateTimeFormatter.ofPattern("HH:mm:ss"));

	/**
	 * 19:00:00
	 */
	public static final LocalTime DAY_TRADE_END_TIME = LocalTime.parse("19:00:00",
			DateTimeFormatter.ofPattern("HH:mm:ss"));

	protected Bar.Frequency __frequency;

	/**
	 * 对于日内周期, 返回从整点时刻 (HH:00:00)为基准的, 包含指定的 dateTime 且距离最近的 IntraDayRange, DayRange 和 MonthRange
	 * 的情况直接使用指定的 dateTime 的 日期 和 月份:
	 * 
	 * @param dateTime dateTime
	 * @param frequency frequency
	 * @return TimeRange
	 * @throws IllegalArgumentException IllegalArgumentException
	 */
	public static TimeRange buildRange(ZonedDateTime dateTime, Bar.Frequency frequency)
			throws IllegalArgumentException {

		TimeRange ret;
		if (frequency.getValue() < Bar.Frequency.DAY.getValue()) {
			ret = new IntraDayRange(dateTime, frequency);
			ret.__frequency = frequency;
			return ret;
		} else if (frequency == Bar.Frequency.DAY) {
			ret = new DayRange(dateTime);
			ret.__frequency = Bar.Frequency.DAY;
			return ret;
		} else if (frequency == Bar.Frequency.MONTH) {
			ret = new MonthRange(dateTime);
			ret.__frequency = Bar.Frequency.MONTH;
			return ret;
		} else {
			throw new IllegalArgumentException("Unsupported frequency: " + frequency);
		}
	}

	/**
	 * 
	 * @return Frequency
	 */
	public Bar.Frequency getFrequency() {

		return __frequency;
	}

	/**
	 * 
	 * @param dateTime dateTime
	 * @return boolean
	 */
	public abstract boolean belongs(ZonedDateTime dateTime);

	/**
	 * 
	 * @return ZonedDateTime
	 */
	public abstract ZonedDateTime getBeginning();

	/**
	 * 1 past the end.
	 * 
	 * @return ZonedDateTime
	 */
	public abstract ZonedDateTime getEnding();

	/*
	 * 
	 */
	@Override
	public String toString() {

		return toString(true);
	}

	/**
	 * 
	 * @param useMarketDateTime useMarketDateTime
	 * @return toString
	 */
	public String toString(boolean useMarketDateTime) {

		String tmpl = "TimeRange(%s) [%s, %s)";
		if (useMarketDateTime) {
			return String.format(tmpl, __frequency, CommonDataUtils.toMarketDatetime(getBeginning()),
					CommonDataUtils.toMarketDatetime(getEnding()));
		} else {
			return String.format(tmpl, __frequency, getBeginning(), getEnding());
		}
	}
}
